using System;
using System.Collections.Generic;
using System.Text;

namespace Eve.Data
{
    public class Type : EveProperty
    {
        private int groupId;
        private string typeName;
        private string description;
        private int graphicId;
        private double radius;
        private double mass;
        private double volume;
        private double capacity;
        private int portionSize;
        private int raceId;
        private double basePrice;
        private bool published;
        private int marketGroupId;
        private double chanceOfDuplicating;

        private Group group;
        private MarketGroup marketGroup;
        private Graphic graphic;
        private Race race;
        private Type metaTypeParent;
        private List<Type> metaTypeChildren;
        private MetaGroup metaGroup;
        private List<TypeAttribute> attributes;
        private List<TypeEffect> effects;
        private Dictionary<RAMActivity, TL2MaterialForTypeWithActivity> tl2Materials;
        private List<ControlTowerResource> ctResources;
        private List<TypeReaction> reactionTypes;

        public Group Group
        {
            get
            {
                if (group == null)
                    group = new Group(db, groupId);
                return group;
            }
        }
        public string Name 
        { 
            get { return typeName; } 
        }
        public string Description 
        { 
            get { return description; } 
        }
        public Graphic Graphic
        {
            get
            {
                if (graphic == null)
                    graphic = new Graphic(db, graphicId);
                return graphic;
            }
        }
        public double Raidus 
        { 
            get { return radius; } 
        }
        public double Mass 
        { 
            get { return mass; } 
        }
        public double Volume 
        { 
            get { return volume; } 
        }
        public double Capacity 
        { 
            get { return capacity; } 
        }
        public int PortionSize 
        { 
            get { return portionSize; } 
        }
        public Race Race
        {
            get
            {
                if (race == null)
                    race = new Race(db, raceId);
                return race;
            }
        }
        public double BasePrice 
        { 
            get { return basePrice; } 
        }
        public bool Published 
        { 
            get { return published; } 
        }
        public MarketGroup MarketGroup
        {
            get
            {
                if (marketGroup == null)
                    marketGroup = new MarketGroup(db, marketGroupId);
                return marketGroup;
            }
        }
        public double ChanceOfDuplicating 
        { 
            get { return chanceOfDuplicating; } 
        }
        public Type MetaTypeParent
        {
            get
            {
                if (metaTypeParent == null)
                {
                    string query = "SELECT invTypes.* FROM invTypes, invMetaTypes WHERE invTypes.typeID=invMetaTypes.parentTypeID AND invMetaTypes.typeID=" + Id;
                    DbDataRow row = db.ExecuteSingle(query);
                    if (row != null) metaTypeParent = new Type(row);
                }
                return metaTypeParent;
            }
        }
        public List<Type> MetaTypeChildren
        {
            get
            {
                if (metaTypeChildren == null)
                {
                    metaTypeChildren = new List<Type>();
                    string query = "SELECT invTypes.* FROM invTypes, invMetaTypes WHERE invTypes.typeID=invMetaTypes.typeID AND invMetaTypes.parentTypeID=" + Id;
                    foreach (DbDataRow row in db.ExecuteQuery(query))
                        metaTypeChildren.Add(new Type(row));
                }
                return metaTypeChildren;
            }
        }
        public MetaGroup MetaGroup
        {
            get
            {
                if (metaGroup == null)
                {
                    string query = "SELECT invMetaGroups.* FROM invMetaGroups, invMetaTypes WHERE invMetaGroups.metaGroupID=invMetaTypes.metaGroupID AND invMetaTypes.typeID=" + Id;
                    DbDataRow row = db.ExecuteSingle(query);
                    if (row != null) metaGroup = new MetaGroup(row);
                }
                return metaGroup;
            }
        }
        public List<TypeAttribute> Attributes
        {
            get
            {
                if (attributes == null)
                {
                    attributes = new List<TypeAttribute>();
                    string query = "SELECT * FROM dgmTypeAttributes WHERE typeID=" + Id;
                    foreach (DbDataRow row in db.ExecuteQuery(query))
                        attributes.Add(new TypeAttribute(row, this));
                }
                return attributes;
            }
        }
        public List<TypeEffect> Effects
        {
            get
            {
                if (effects == null)
                {
                    effects = new List<TypeEffect>();
                    string query = "SELECT * FROM dgmTypeEffects WHERE typeID=" + Id;
                    foreach (DbDataRow row in db.ExecuteQuery(query))
                        effects.Add(new TypeEffect(row, this));
                }
                return effects;
            }
        }
        public Dictionary<RAMActivity, TL2MaterialForTypeWithActivity> TL2Materials
        {
            get
            {
                if (tl2Materials == null)
                {
                    tl2Materials = new Dictionary<RAMActivity, TL2MaterialForTypeWithActivity>();
                    string query = "SELECT * FROM TL2MaterialsForTypeWithActivity WHERE typeID=" + Id;
                    foreach (DbDataRow row in db.ExecuteQuery(query))
                    {
                        TL2MaterialForTypeWithActivity twa = new TL2MaterialForTypeWithActivity(row, this);
                        tl2Materials[twa.Activity] = twa;
                    }
                }
                return tl2Materials;
            }
        }
        public List<ControlTowerResource> ControlTowerResources
        {
            get
            {
                if (ctResources == null)
                {
                    ctResources = new List<ControlTowerResource>();
                    string query = "SELECT * FROM invControlTowerResources WHERE controlTowerTypeID=" + Id;
                    foreach (DbDataRow row in db.ExecuteQuery(query))
                        ctResources.Add(new ControlTowerResource(row, this));
                }
                return ctResources;
            }
        }
        public List<TypeReaction> ReactionTypes
        {
            get
            {
                if (reactionTypes == null)
                {
                    reactionTypes = new List<TypeReaction>();
                    string query = "SELECT * FROM invTypeReactions WHERE reactionTypeID=" + Id;
                    foreach (DbDataRow row in db.ExecuteQuery(query))
                        reactionTypes.Add(new TypeReaction(row, this));
                }
                return reactionTypes;
            }
        }

        internal Type(DbDataRow dr)
            : base(dr.Database, EvePropertyType.Type, dr["typeID"])
        {
            Fill(dr);
        }
        internal Type(Database db, int id)
            : base(db, EvePropertyType.Type, id)
        {
            Fill(db.ExecuteSingle("SELECT * FROM invTypes WHERE typeID=" + id));
        }
        private void Fill(DbDataRow dr)
        {
            groupId = dr["groupID"];
            typeName = dr["typeName"];
            description = dr["description"];
            graphicId = dr["graphicID"];
            radius = dr["radius"];
            mass = dr["mass"];
            volume = dr["volume"];
            capacity = dr["capacity"];
            portionSize = dr["portionSize"];
            raceId = dr["raceID"];
            basePrice = dr["basePrice"];
            published = dr["published"];
            marketGroupId = dr["marketGroupID"];
            chanceOfDuplicating = dr["chanceOfDuplicating"];
        }
    }
}
